﻿#region License
/* ---------------------------------------------------------------- *
 *
 * This file is part of the Xcoordination Application Space
 * ("XcoAppSpace") http://www.xcoordination.com
 *
 * Copyright (C) 2009 Xcoordination http://www.xcoordination.com
 *
 * XcoAppSpace is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General
 * Public License as published by the Free Software Foundation.
 *
 * XcoAppSpace is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/
 * or write to the Free Software Foundation, Inc., 51 Franklin
 * Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * ---------------------------------------------------------------- */
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Ccr.Core;
using XcoAppSpaces.Contracts.Messaging;
using XcoAppSpaces.Contracts.Service;

namespace XcoAppSpaces.Contracts.CcrWiring
{
	/// <summary>
	/// Service for wiring workers, worker proxies and remote ports with the Ccr
	/// </summary>
	public interface ICcrWirer : IXcoService
	{
		/// <summary>
		/// Creates a new Worker and wires the worker ports with the message handlers contained in the worker class.
		/// </summary>
		/// <typeparam name="TMessageContract">The contract type of the worker.</typeparam>
		/// <typeparam name="TImplementation">The implementation type of the worker.</typeparam>
		/// <param name="dpq">The dispatcher queue that should be used for wiring the worker, or null if space's the default dispatcher queue should be used.</param>
		/// <returns>A WorkerInfo object containing the worker instance and additional information that has been gathered during the worker wiring.</returns>
		WorkerInfo<TMessageContract> CreateWorker<TMessageContract, TImplementation>(DispatcherQueue dpq)
			where TMessageContract : IPort
			where TImplementation : TMessageContract, new();


		/// <summary>
		/// Wires a given worker's ports with its message handlers.
		/// </summary>
		/// <typeparam name="TMessageContract">The contract type of the worker.</typeparam>
		/// <param name="worker">The worker instance.</param>
		/// <param name="dpq">The dispatcher queue that should be used for wiring the worker, or null if space's the default dispatcher queue should be used.</param>
		/// <returns>A WorkerInfo object containing the worker instance and additional information that has been gathered during the worker wiring.</returns>
		WorkerInfo<TMessageContract> WireWorker<TMessageContract>(TMessageContract worker, DispatcherQueue dpq)
			where TMessageContract : IPort;


		/// <summary>
		/// Removes all registered receiver tasks from all ports of the worker.
		/// </summary>
		/// <param name="worker">The worker that should be unwired.</param>
		void UnwireWorker(IPort worker);


		/// <summary>
		/// Creates a worker proxy for a remote worker from the given parameters.
		/// </summary>
		/// <typeparam name="TMessageContract">The contract type of the worker (must have an empty constructor so it can be instantiated as a proxy).</typeparam>
		/// <param name="proxyInfo">Information that is needed to create the worker proxy, like name and address of the worker.</param>
		/// <returns>The created worker proxy.</returns>
		TMessageContract CreateWorkerProxy<TMessageContract>(WorkerProxyInfo proxyInfo)
			where TMessageContract : IPort, new();


		/// <summary>
		/// Gets a serialization info object that contains all information that is needed by the receiving space
		/// to deserialize the worker. The current serialization context can be used to get the local adress, and
		/// to register the port at the local space and get a unique id for the port, if it is not already
		/// a remote port.
		/// </summary>
		/// <param name="port">The port to be serialized.</param>
		/// <returns>Object containing the info that must be sent to the remote space for deserialization of the port.</returns>
		XcoPortSerializationInfo GetPortSerializationInfo(IPort port);


		/// <summary>
		/// Wires a port using the given serialization info, so that it is ready for remote communication. The
		/// current serialization context can be used to get the name of the communication service that should be
		/// used to send messages to the original port.
		/// </summary>
		/// <param name="port">The port to be wired.</param>
		/// <param name="portSerializationInfo">Info that is needed for wiring the remote port, like the port's id and remote address.</param>
		void WireRemotePort(IPort port, XcoPortSerializationInfo portSerializationInfo);
	}
}
